﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace Maydew.Windows.Forms.Controls.FlexiCell
{
    /// <summary>
    /// 为单元格提供编辑器。
    /// </summary>
    public class CellEditor : IDisposable, ICloneable
    {
        #region " 事件 "
        /// <summary>
        /// 当键盘按键按下时发生。
        /// </summary>
        public event KeyEventHandler KeyDown;
        #endregion

        #region " 私有变量 "
        /// <summary>
        /// 获取或设置编辑器控件。
        /// </summary>
        private Control _editor;
        /// <summary>
        /// 获取或设置所属单元格。
        /// </summary>
        private Cell _owner;
        #endregion

        #region " 构造函数 "
        /// <summary>
        /// 初始化 CellEditor 类的新实例。
        /// </summary>
        public CellEditor()
        {
        }
        #endregion

        #region " 属性 "
        /// <summary>
        /// 获取是否允许键盘输入。
        /// </summary>
        public virtual bool AllowKeyboard
        {
            get { return true; }
        }
        /// <summary>
        /// 获取或设置编辑器控件。
        /// </summary>
        protected virtual Control Editor
        {
            get { return _editor; }
            set
            {
                if (_editor != value)
                {
                    _editor = value;
                    _editor.KeyDown += new KeyEventHandler(_editor_KeyDown);
                }
            }
        }
        /// <summary>
        /// 获取或设置所属单元格。
        /// </summary>
        internal protected virtual Cell Owner
        {
            get { return _owner; }
            set
            {
                _owner = value;
                if (_owner != null)
                {
                    if (_owner.Editing)
                    {
                        SetEditVisible(_owner.Editing);
                        _owner.Canvas.Controls.Add(_editor);
                    }
                    else
                    {
                        _editor.Visible = false;
                    }
                    _owner.ValueChanged += new EventHandler(_owner_ValueChanged);
                    _owner.EditingChanged += new EventHandler(_owner_EditingChanged);
                }
            }
        }

        
        #endregion

        #region " 事件处理 "
        /// <summary>
        /// 当键盘按键按下时发生。
        /// </summary>
        /// <param name="sender">事件对象。</param>
        /// <param name="e">事件参数。</param>
        private void _editor_KeyDown(object sender, KeyEventArgs e)
        {
            if (KeyDown != null) KeyDown(this, e);
        }
        /// <summary>
        /// 当单元格 Editing 属性值改变后发生。
        /// </summary>
        /// <param name="sender">事件对象。</param>
        /// <param name="e">事件参数。</param>
        private void _owner_EditingChanged(object sender, EventArgs e)
        {
            if (_owner.Editing)
            {
                OnSetEditorValue();
            }
            else
            {
                OnGetEditorValue();
            }
            SetEditVisible(_owner.Editing);
        }
        /// <summary>
        /// 当单元格 Value 属性值改变后发生。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _owner_ValueChanged(object sender, EventArgs e)
        {
            if (_editor.Parent != _owner.Canvas)
            {
                _owner.Canvas.Controls.Add(_editor);
            }
            OnSetEditorValue();
        }
        #endregion

        #region " 友元方法 "
        /// <summary>
        /// 设置编辑器值时。
        /// </summary>
        protected virtual void OnSetEditorValue()
        {
        }
        /// <summary>
        /// 获取编辑器值时。
        /// </summary>
        protected virtual void OnGetEditorValue()
        {
        }
        /// <summary>
        /// 显示编辑器时。
        /// </summary>
        protected virtual void OnShowEditor()
        {
            Rectangle rect = _owner.Bounds;
            //rect.Inflate(-1, -1);
            rect.X += 1;
            rect.Y += 1;
            rect.Width -= 1;
            rect.Height -= 1;
            _editor.Location = rect.Location;
            _editor.Size = rect.Size;
        }
        #endregion

        #region " 方法 "
        /// <summary>
        /// 显示编辑器。
        /// </summary>
        public virtual void ShowEditor()
        {
            SetEditVisible(true);
        }
        /// <summary>
        /// 绘制编辑器。
        /// </summary>
        /// <param name="g">绘图参数。</param>
        public virtual void Painting(Graphics g)
        {

        }
        #endregion

        #region " 私有方法 "
        /// <summary>
        /// 设置单元格可见状态。
        /// </summary>
        /// <param name="visible">是否可见。</param>
        private void SetEditVisible(bool visible)
        {
            if (_editor.Parent != _owner.Canvas)
            {
                _owner.Canvas.Controls.Add(_editor);
            }

            if (visible)
            {
                OnShowEditor();
                _owner.Editing = true;
                _editor.Visible = true;
                _editor.Focus();
            }
            else
            {
                _owner.Editing = false;
                _editor.Visible = false;
            }

        }
        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposed)
        {
            if (disposed)
            {
                if (_owner != null)
                {
                    _owner.ValueChanged -= new EventHandler(_owner_ValueChanged);
                    _owner.EditingChanged -= new EventHandler(_owner_EditingChanged);
                    _owner = null;
                }
                if (_editor != null)
                {
                    if (_editor.Parent != null) _editor.Parent.Controls.Remove(_editor);
                    _editor.KeyDown -= new KeyEventHandler(_editor_KeyDown);
                    _editor.Dispose();
                    _editor = null;
                }
            }
        }
        #endregion

        #region ICloneable Members

        public virtual object Clone()
        {
            return new CellEditor();
        }

        #endregion
    }    
}

